package com.smart.community.common.base.handler;

import cn.hutool.core.util.ReflectUtil;
import com.smart.community.common.base.dto.ArgsErrorInfo;
import com.smart.community.common.base.ex.BaseException;
import com.smart.community.common.base.result.ResponseResult;
import com.smart.community.common.base.result.ResultStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhangwei
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseResult<Object> handlerException(Exception ex) {
        ex.printStackTrace();
        log.error("错误的信息:{}", ex.getMessage());
        return ResponseResult.error();
    }


    @ExceptionHandler(BaseException.class)
    public ResponseResult<Object> handlerException(BaseException ex) {
        ex.printStackTrace();
        return ResponseResult.error(ex.getResultStatus());
    }

    /**
     * 属性名  错误信息
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseResult<List<ArgsErrorInfo>> handlerException(ConstraintViolationException ex) {
        ex.printStackTrace();
        return ResponseResult.error(ResultStatus.ARGS_VALID_ERROR,
                ex.getConstraintViolations().stream().map(
                        violation -> {
//                            获取到违反约束的路径字段以及错误信息
                            List<Path.Node> nodeList = (List<Path.Node>) ReflectUtil.getFieldValue(violation.getPropertyPath(), "nodeList");
//                            创建ArgsErrorInfo对象
                            return ArgsErrorInfo.builder().filedName(nodeList.get(nodeList.size() - 1)
                                    .getName()).errorMessage(violation.getMessage()).build();
                        }
                ).collect(Collectors.toList()));
    }

    /**
     * message
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(BindException.class)
    public ResponseResult<List<ArgsErrorInfo>> handlerException(BindException ex) {
        ex.printStackTrace();
        return ResponseResult.error(ResultStatus.ARGS_VALID_ERROR,
                ex.getBindingResult().getFieldErrors().stream()
                .map(fieldError -> ArgsErrorInfo.builder().filedName(fieldError.getField())
                        .errorMessage(fieldError.getDefaultMessage()).build()).collect(Collectors.toList()));
    }

}
